public class ThirdOrderForward extends Forward {

  public ThirdOrderForward(ThirdOrderHMM hmm, Object x[]) {
    super(hmm, x);
    L = x.length;
    f = new double[L+1][hmm.nstate];
    f[0][0] = 0;
    for (int k=1; k<hmm.nstate; k++) f[0][k] = Double.NEGATIVE_INFINITY;
    for (int i=1; i<=L; i++) f[i][0] = Double.NEGATIVE_INFINITY;
    for (int i=1; i<=L; i++) for (int ell=1; ell<hmm.nstate; ell++) {
        double sum = Double.NEGATIVE_INFINITY;
        for (int jj=0; jj<hmm.nstate; jj++) for (int j=0; j<hmm.nstate; j++) for (int k=0; k<hmm.nstate; k++) sum = logplus(sum, f[i-1][k] + hmm.loga[jj][j][k][ell]);
        f[i][ell] = hmm.loge[ell][hmm.getSym(x[i-1])] + sum;
      }    
  }

  public ThirdOrderForward ( ThirdOrderMM mm , Object[] x ) {
	super(mm, x);
        L = x.length;
        f = new double[L+1][1];
	f[0][0] = Double.NEGATIVE_INFINITY;
	f[1][0] = mm.loge[0][0][0][mm.getSym(x[0])];
        f[2][0] = logplus(f[1][0] , mm.loge[0][0][mm.getSym(x[0])][mm.getSym(x[1])]);
        f[3][0] = logplus(f[2][0] , mm.loge[0][mm.getSym(x[0])][mm.getSym(x[1])][mm.getSym(x[2])]);
	for (int i=3; i < x.length; i++) f[i+1][0] = logplus(f[i][0] , mm.loge[mm.getSym(x[i-3])][mm.getSym(x[i-2])][mm.getSym(x[i-1])][mm.getSym(x[i])]);
  }

}
